import serial
import time
import os
import sys
import random
import re
import subprocess
import threading


# 定义常量
DEBUG_PORT = "COM4"
AT_PORT = "COM39"
BAUDRATE = 115200
# 定义变量
at_serial = None
debug_serial = None
#记录运行次数
runTimes		= 0
#log文件
DEBUG_LOG = ""
ADB_LOG = ""
AT_LOG = ""

# 创建日志文件
def createLogFile():
    global DEBUG_LOG, ADB_LOG, AT_LOG
    timestamp = time.strftime("%Y-%m-%d_%H_%M_%S", time.localtime())
    DEBUG_LOG = f"DEBUG_LOG_{timestamp}.log"
    ADB_LOG = f"ADB_LOG_{timestamp}.log"
    AT_LOG = f"AT_LOG_{timestamp}.log"
    
    with open(DEBUG_LOG, 'w', encoding='utf-8') as file:
        file.write("DEBUG 日志开始记录...\n")
    
    with open(ADB_LOG, 'w', encoding='utf-8') as file:
        file.write("ADB 日志开始记录...\n")
        
    with open(AT_LOG, 'w', encoding='utf-8') as file:
        file.write("AT 日志开始记录...\n")
        
# 写日志
def write_log(log, logFile):
    with open(logFile, 'a', encoding='utf-8') as file_object:
        file_object.write(str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + log + "\r\n")
        now_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        print("[" + now_time+ "]" + " " + log)

#Send at instruction
def at_write(command, timeout, at_port_opened, at_result,RDY=0,CPIN=0):
	at_command = command.encode("UTF-8")
	at_port_opened.write(at_command)
 
#读取at口返回
def at_read(serial_port, logFile=""):
 rec_str = ''
 while (True):
  time.sleep(1)
  lenth = serial_port.inWaiting()
  if lenth > 0:
   rec_str = serial_port.read(size=lenth)
   try:
    rec_str = re.sub('\\x1b.*?m', "", rec_str.decode("UTF-8"), 0, re.I)
    if logFile != "":
     with open(logFile, 'a') as file_object:
      rec_str = str(time.time()) + ":" + str(
       time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + rec_str
      file_object.write(
       str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + rec_str + "\r\n")
    return rec_str
   except:
    return ""
  else:
   break
 return rec_str

# 登录设备
def loginDevice():
 global DEBUG_LOG
 #确认登录失败的条件，或者，不可能失败
 while True:
#   print("等待登录... ... ")
  write_log("等待登录... ... ", DEBUG_LOG)
  time.sleep(3)
  at_write("\r\n",3,debug_serial,"OK")
  result = at_read(debug_serial)

  with open(DEBUG_LOG, 'a') as file_object:
   file_object.write(result)

  if "login:" in result:
   at_write("root\r\n",3,debug_serial,"OK")
#    print("账号输入成功")
   write_log("账号输入成功", DEBUG_LOG)
   time.sleep(2)
   at_write("oelinux123\r\n",3,debug_serial,"OK")
#    print("密码输入成功")
   write_log("密码输入成功", DEBUG_LOG)
  elif "~ #" in result:
#    print("登录成功")
   write_log("登录成功", DEBUG_LOG)
   break
  else:
   continue 

#检查debug口通信状态
def check_port_status():
 global debug_serial
 if debug_serial == None:
  try:
   debug_serial = serial.Serial(DEBUG_PORT,BAUDRATE)
  except:
   print("端口连接失败，请检查端口")
   sys.exit()

# 写入运行次数到日志
def writeRuntimesToLog():
 global runTimes
 with open(DEBUG_LOG, 'a+') as file_object:
  file_object.write("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
#  print("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
 with open(AT_LOG, 'a+') as file_object:
  file_object.write("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
#  print("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
 with open(ADB_LOG, 'a+') as file_object:
  file_object.write("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
 print("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
 runTimes += 1
 
#发送AT指令
def send_at_command(command):
        # 打开串口
        ser = serial.Serial(AT_PORT, BAUDRATE)
        ser.write((command + "\r\n").encode())
        ser.write(("\r\n").encode())
        time.sleep(6)
        response = ser.read_all().decode()
        ser.close()
        # write_log(f"at指令{command}执行结果:{response}",AT_LOG)
        with open(AT_LOG, 'a', encoding='utf-8') as file_object:
            file_object.write(str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + response + "\r\n")
        return response
        
#发送adb命令          
def send_adb_command(command):
    try:
        # 使用 subprocess 模块执行 adb shell 命令
        result = subprocess.run(['adb', 'shell', command], capture_output=True, text=True)
        with open(ADB_LOG, 'a', encoding='utf-8') as file_object:
            file_object.write(str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + result.stdout + "\r\n")
        # 返回命令的输出结果
        return result.stdout
    except Exception as e:
        return str(e)


#查看GPS 的进程
def check_gps_process():
    # 使用 adb shell 命令查看 GPS 进程
    result = send_adb_command("ps |grep location_hal_daemon")
    # print(result)
    write_log(result, ADB_LOG)  # 写入日志:
    return result
#提取gps进程的pid
def extract_pid_from_gps_process(data):
    # 使用正则表达式提取 gps 的进程号
    match = re.search(r'(\d+)\s+gps\s+', data)
    if match:
        gps_pid = match.group(1)
        # print(f"gps 的进程号是: {gps_pid}")
        write_log(f"gps 的进程号是: {gps_pid}", ADB_LOG)  # 写入日志
    else:
        # print("未找到 gps 的进程号")
        write_log("未找到 gps 的进程号", ADB_LOG)  # 写入日志
    return gps_pid 

#查看进程占用
def check_process_memory_usage(pid):
    # 使用 adb shell 命令查看进程内存使用情况
    result = send_adb_command("cat /proc/{}/status |grep RSS".format(pid))
    # print(result)
    write_log(result, ADB_LOG)  # 写入日志
    rss_value = int(result.split()[1])
    return rss_value

def calculate_rss_diff(data, threshold):
    if len(data) < 2:
        return  # 如果数据不足两次，不进行比较
    
    # 当前比较的索引
    current_index = len(data) - 1
    previous_index = current_index - 1
    
    # 当前值与上一次值
    current = data[current_index]
    previous = data[previous_index]
    difference = abs(current - previous)  # 计算差值
    
    if difference > threshold:
        write_log(f"警告：第{current_index + 1}次 ({current} KB) 与第{previous_index + 1}次 ({previous} KB) 的差值 {difference} KB，超过阈值 {threshold} KB。", ADB_LOG)
    else:
        write_log(f"正常：第{current_index + 1}次 ({current} KB) 与第{previous_index + 1}次 ({previous} KB) 的差值 {difference} KB。", ADB_LOG)

            
            
#启动GNSS服务
def start_gnss_service():
    at_write("gnss --start\r\n",3,debug_serial,"OK")
    at_read(debug_serial) # 读取返回结果
    
def main():
    memory_usages = []
    threshold = 10 # 设置阈值为 10 KB
    # 检查串口连接状态，确保 debug_serial 已连接
    check_port_status() 
    createLogFile()  # 确保日志文件被创建
    # 打印日志路径，确认日志文件已创建
    print(f"DEBUG_LOG: {DEBUG_LOG}, ADB_LOG: {ADB_LOG}, AT_LOG: {AT_LOG}")
    # 检查串口连接状态，确保 debug_serial 已连接
    check_port_status() 
    # 登录设备
    loginDevice()
    start_gnss_service()
    while True:
        data = check_gps_process()
        pid = extract_pid_from_gps_process(data)
        memory_usage = check_process_memory_usage(pid)
        memory_usages.append(memory_usage)
        calculate_rss_diff(memory_usages, threshold)  # 设置阈值为
        time.sleep(2)  # 每隔 2 秒检查一次
        
if __name__ == "__main__":
    main()